package org.wpahs.ahn.rssfeed;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Html;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.webkit.URLUtil;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.wpahs.ahn.rssfeed.DB.DBMyFeed;
import org.xml.sax.SAXException;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

public class FindFeedFragment extends Fragment {


    private OnFragmentInteractionListener mListener;
    private ListView mSearchResults;
    private EditText mSearchBox;
    private List<SearchResult> mResults = new ArrayList<>();
    private SearchAdapter mAdapter;
    private AlertDialog.Builder mDialogBuilder;
    private FeedData mCurrentFeedData;
    private View mDialogView;
    private AlertDialog mLoadingDialog;

    public static FindFeedFragment newInstance() {
        FindFeedFragment fragment = new FindFeedFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public FindFeedFragment() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_find_feed, container, false);
        mSearchBox = (EditText) v.findViewById(R.id.SearchBox);
        mSearchResults = (ListView) v.findViewById(R.id.SearchResults);
        mSearchResults.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                final View dv = view;
                final SearchResult selectedResult = mAdapter.getItem(position);
                DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case DialogInterface.BUTTON_POSITIVE:
                                //Yes button clicked
                                try {

                                    DBMyFeed dbMyFeed = new DBMyFeed(dv.getContext());
                                    MyFeed myFeed = new MyFeed();
                                    myFeed.setTitle(mCurrentFeedData.getTitle());
                                    myFeed.setUrl(mCurrentFeedData.getFeedUrl());
                                    int newFeedId = dbMyFeed.addFeed(myFeed);
                                    ((SettingsActivity) getActivity()).processFeed(newFeedId);
                                } catch (Exception ex) {
                                    Toast.makeText(dv.getContext(), ex.getMessage(), Toast.LENGTH_SHORT).show();
                                }
                                break;

                            case DialogInterface.BUTTON_NEGATIVE:
                                //No button clicked
                                break;
                        }
                    }
                };

                mDialogBuilder = new AlertDialog.Builder(view.getContext());
                LayoutInflater inflater = (LayoutInflater) view.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                mDialogView = inflater.inflate(R.layout.searchresultload_layout, null, false);
                mDialogBuilder.setView(mDialogView);
                TextView tTitle = (TextView) mDialogView.findViewById(R.id.SRLTitle);
                tTitle.setText("Loading...");
                new FeedLoad(selectedResult.getUrl()).execute();
                mDialogBuilder.setPositiveButton("Add", dialogClickListener)
                        .setNegativeButton("Cancel", dialogClickListener).show();

            }
        });

        mDialogView = inflater.inflate(R.layout.searchresultload_layout, null, false);
        mSearchBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                final String query = mSearchBox.getText().toString().trim();
                if (URLUtil.isValidUrl(query)) {
                    DBMyFeed dbMyFeed = new DBMyFeed(v.getContext());
                    MyFeed myFeed = new MyFeed();
                    myFeed.setTitle(query);
                    myFeed.setUrl(query);
                    int newFeedId = dbMyFeed.addFeed(myFeed);
                    Toast.makeText(v.getContext(), "Added " + myFeed.getTitle(), Toast.LENGTH_SHORT).show();
                    ((SettingsActivity) getActivity()).processFeed(newFeedId);
                    return true;
                } else {
                    AlertDialog.Builder aBuilder = new AlertDialog.Builder(v.getContext());
                    aBuilder.setCancelable(true);
                    aBuilder.setMessage("Searching for " + query);
                    mLoadingDialog = aBuilder.show();
                    v.post(new Runnable() {
                        @Override
                        public void run() {
                            new FeedSearch(query).execute();
                        }
                    });
                    return true;
                }
            }
        });
        /*
        mSearchBox.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_SEARCH &&
                        event.getAction() == KeyEvent.ACTION_UP) {
                    final String query = mSearchBox.getQuery().toString().trim();
                    if (URLUtil.isValidUrl(query)) {
                        DBMyFeed dbMyFeed = new DBMyFeed(v.getContext());
                        MyFeed myFeed = new MyFeed();
                        myFeed.setTitle(query);
                        myFeed.setUrl(query);
                        int newFeedId = dbMyFeed.addFeed(myFeed);
                        Toast.makeText(v.getContext(), "Added " + myFeed.getTitle(), Toast.LENGTH_SHORT).show();
                        ((SettingsActivity) getActivity()).processFeed(newFeedId);
                        return true;
                    } else {
                        AlertDialog.Builder aBuilder = new AlertDialog.Builder(v.getContext());
                        aBuilder.setCancelable(true);
                        aBuilder.setMessage("Searching for " + query);
                        mLoadingDialog = aBuilder.show();
                        v.post(new Runnable() {
                            @Override
                            public void run() {
                                new FeedSearch(query).execute();
                            }
                        });
                        return true;
                    }
                }
                return false;
            }
        });
        */
        return v;
    }


    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    static class SearchResultHolder {
        TextView tvTitle;
        TextView tvUrl;
        TextView tvSnippet;
        TextView tvLink;
        Button btnAdd;
        int position;
    }

    public class SearchAdapter extends ArrayAdapter<SearchResult> {
        Context mContext;

        public SearchAdapter(Context context, int resource, List<SearchResult> objects) {
            super(context, resource, objects);
            mContext = context;

        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View resultView = inflater.inflate(R.layout.searchresult_layout, parent, false);
            SearchResult result = this.getItem(position);
            final SearchResultHolder holder;

            if(resultView.getTag() == null){
                holder = new SearchResultHolder();
                holder.tvLink = (TextView)resultView.findViewById(R.id.SRLink);
                holder.tvSnippet = (TextView)resultView.findViewById(R.id.SRSnippet);
                holder.tvTitle = (TextView)resultView.findViewById(R.id.SRTitle);
                holder.tvUrl = (TextView)resultView.findViewById(R.id.SRUrl);
                resultView.setTag(holder);
            }else{
                holder = (SearchResultHolder)resultView.getTag();
            }
            holder.position=position;
            holder.tvTitle.setText(Html.fromHtml(result.getTitle()));
            holder.tvUrl.setText(result.getUrl());
            holder.tvSnippet.setText(Html.fromHtml(result.getContentSnippet()));
            holder.tvLink.setText(result.getLink());

            return resultView;
        }
    }

    public class FeedSearch extends AsyncTask<Void,Void,List<SearchResult>> {
        private String url;
        private Exception mException;
        public FeedSearch(String searchString){
            try {
                searchString = URLEncoder.encode(searchString.trim(), "utf-8");
                url = "https://ajax.googleapis.com/ajax/services/feed/find?v=1.0&q=" + searchString;
            } catch (UnsupportedEncodingException e) {
                url=searchString;
                //mSearchBox.setError(e.getMessage());
            }
        }

        @Override
        protected List<SearchResult> doInBackground(Void... params) {
            List<SearchResult> results = new ArrayList<SearchResult>();
            HttpURLConnection connection = null;
            try {
                URL urlConnection = new URL(url);

                connection = (HttpsURLConnection) urlConnection
                        .openConnection();


                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"), 8);
                StringBuilder sb = new StringBuilder();

                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
                JSONObject response = new JSONObject(sb.toString());
                if(response.has("responseData")) {
                    JSONObject responseData = response.getJSONObject("responseData");
                    JSONArray entries = responseData.getJSONArray("entries");
                    for (int entryIdx = 0; entryIdx < entries.length(); entryIdx++) {
                        SearchResult result = new SearchResult();
                        JSONObject entry = entries.getJSONObject(entryIdx);
                        result.setContentSnippet((entry.has(SearchResult.CONTENTSNIPPET) ? entry.getString(SearchResult.CONTENTSNIPPET) : null));
                        result.setTitle((entry.has(SearchResult.TITLE) ? entry.getString(SearchResult.TITLE) : null));
                        result.setUrl((entry.has(SearchResult.URL) ? entry.getString(SearchResult.URL) : null));
                        result.setLink((entry.has(SearchResult.LINK) ? entry.getString(SearchResult.LINK) : null));

                        if (result.getUrl() != null && result.getUrl().length() > 0) { // no feed url.  leave it
                            results.add(result);
                        }
                    }
                }
            }catch (MalformedURLException e){
                mException = e;
            } catch (IOException e) {
               mException = e;
            } catch (JSONException e) {
                mException = e;
            }finally{
                connection.disconnect();
            }

            return results;
        }

        @Override
        protected void onPostExecute(List<SearchResult> results){
            mResults.clear();
            if (mAdapter == null) {
                mAdapter = new SearchAdapter(getActivity(), R.layout.searchresult_layout, mResults);
                mSearchResults.setAdapter(mAdapter);
            }
            if(mException == null) {
                mResults.addAll(results);
            }else{
                //mSearchBox.setError((mException.getMessage() == null ? "MysteryError" : mException.getMessage()));
                Toast.makeText(getActivity(),(mException.getMessage() == null ? "MysteryError" : mException.getMessage()),Toast.LENGTH_SHORT).show();
            }
            if(results.size() ==0){
               //mSearchBox.setError("I Can't Find Them");
                Toast.makeText(getActivity(),"I Can't Find Them",Toast.LENGTH_SHORT).show();
            }
            mAdapter.notifyDataSetChanged();
            mSearchResults.invalidateViews();
            mLoadingDialog.cancel();

        }
    }

    public class FeedLoad extends AsyncTask<Void,Void,FeedData> {
        private String mUrl;
        private Exception mException;
        public FeedLoad(String url){
            mUrl = "https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=" + url;
        }

        @Override
        protected FeedData doInBackground(Void... params) {
            FeedData result = null;
            HttpURLConnection connection = null;
            try {
                URL urlConnection = new URL(mUrl);

                connection = (HttpsURLConnection) urlConnection
                        .openConnection();


                connection.setDoInput(true);
                connection.connect();
                InputStream input = connection.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"), 8);
                StringBuilder sb = new StringBuilder();

                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
                JSONObject response = new JSONObject(sb.toString());
                if(response.has("responseData")) {
                    JSONObject responseData = response.getJSONObject("responseData");
                    JSONObject feed = responseData.getJSONObject("feed");
                    result = new FeedData();
                    result.setTitle((feed.has(FeedData.TITLE) ? feed.getString(FeedData.TITLE) : null));
                    result.setLink((feed.has(FeedData.LINK) ? feed.getString(FeedData.LINK) : null));
                    result.setDescription((feed.has(FeedData.DESCRIPTION) ? feed.getString(FeedData.DESCRIPTION) : null));
                    result.setFeedUrl((feed.has(FeedData.FEEDURL) ? feed.getString(FeedData.FEEDURL) : null));
                    JSONArray entries = feed.getJSONArray("entries");
                    if (entries != null && entries.length() > 0) {
                        for (int idx = 0; idx < entries.length(); idx++) {
                            JSONObject jo = entries.getJSONObject(idx);
                            FeedEntry fe = new FeedEntry();
                            fe.setTitle((jo.has(FeedEntry.TITLE) ? feed.getString(FeedEntry.TITLE) : null));
                            fe.setLink((jo.has(FeedEntry.LINK) ? feed.getString(FeedEntry.LINK) : null));
                            fe.setSnippet((jo.has(FeedEntry.SNIPPET) ? feed.getString(FeedEntry.SNIPPET) : null));
                            result.addEntry(fe);
                        }
                    }
                }

            }catch (MalformedURLException e){
                mException = e;
            } catch (IOException e) {
                mException = e;
            } catch (JSONException e) {
                mException = e;
            }finally{
                connection.disconnect();
            }

            return result;
        }

        @Override
        protected void onPostExecute(FeedData result){
            mCurrentFeedData = result;
            mDialogBuilder.setMessage("");
            if(mException != null) {
                mDialogBuilder.setTitle(mException.getMessage());
            }else{
                if(result != null) {
                    mDialogBuilder.setTitle(result.getTitle());
                    TextView tTitle = (TextView) mDialogView.findViewById(R.id.SRLTitle);
                    TextView tDescription = (TextView) mDialogView.findViewById(R.id.SRLDescription);
                    TextView tLink = (TextView) mDialogView.findViewById(R.id.SRLink);
                    if (tTitle != null) tTitle.setText(result.getTitle());
                    if (tDescription != null) tDescription.setText(result.getDescription());
                    if (tLink != null) tLink.setText(result.getFeedUrl());
                    mDialogView.invalidate();
                }else{
                    mDialogBuilder.setTitle("no data");
                }
            }

        }
    }




}
